#pragma once

#include <stdint.h>
#include <stdbool.h>
#include "predef.h"

// define M0 flash local config file version and address and size
#define ZQM_CFG_FILE_VER	21
#define ZQM_CFG_FILE_ADDR 	(0x00000000 + EEPROM_PAGE_SIZE * 1)
#define ZQM_CFG_FILE_SIZE 	EEPROM_PAGE_SIZE

// 各机型参数定义 ----------------------------------------------------------------------------------------
// 3001001039控制模块,SC-760,4G/WIFI/压机控制/门开关/电池/温控/灯控 /不含卡
#define AKM_DEV_NAME 					"SD-450S"
#define AKM_DEV_TYPE					DEV_LI_COOL
#define AKM_CTRL_TYPE					CTRL_4GCTRL
#define AKM_CTRL_FUNC 					((1<<FUN_TCM)|(1<<FUN_COMPRESS)|(1<<FUN_DOORSW)|(1<<FUN_TEMPCTRL))
#define AKM_MODULE_TYPE					MDU_4G
#define ZQ_COMM_PLATFORM				8850		// which BLE platform to be used, 0 - NA; 8910 - 8910 platform; 582 - 582 platform

#define ZQ_M0_MAINBOARD					MBT_582_8850			
#define ZQ_DISPLAY_PANEL_TYPE 			DPT_SPLIT_1
// select platform ble function, 0 - NA; 8910 - 8910 platform; 582 - 582 platform
#define ZQ_BLE_PLATFORM				    0
// 定义是否海外版本, 对CAT1拨号APN设置有影响
#define ZQ_APN_ABROAD 					0

// 冷藏/冷冻/加热柜 refer ZqCtrlMode, cool = CTRL_MODE_COOL; freeze = CTRL_MODE_FREEZE; heater = CTRL_MODE_HOT, may multi functions, ex. cool | freeze | heater
#define ZQ_BOX_MODE						CTRL_MODE_COOL
// hard switch function(local system switch)
#define ZQ_FUNC_HARD_SWITCH				0
// soft switch function
#define ZQ_FUNC_SOFT_SWITCH				0
// door1 function
#define ZQ_FUNC_DOOR1					1
// door2 function
#define ZQ_FUNC_DOOR2					0
// human detection function
#define ZQ_FUNC_HUMAN					0
// battery function
#define ZQ_FUNC_BATTERY                 0
// power meter function
#define ZQ_FUNC_POW_METER				0
// light function
#define ZQ_FUNC_LIGHT					0
// Active defrosting function
#define ZQ_FUNC_ACTIVE_DEFROST			1
// support diagnostic function
#define ZQ_FUNC_DIAGNOSTIC				0
// support buzzor function
#define ZQ_FUNC_BUZZOR					0

// define sensor(adc) channel
#if(ZQ_M0_MAINBOARD	== MBT_582_8850)   // 1 = akm general
	// define ADC channel
	#define ADC_CH_NTC1     	9  				//TEM_SENSOR1
	#if (CFG_DEVICE_TYPE == 1004)
		#define ADC_CH_NTC2     	8  			//TEM_SENSOR2
	#else
		#define ADC_CH_NTC2     	0x80 		//TEM_SENSOR2 - 无效
	#endif
	#define ADC_CH_BATT     	5  				//ADC_BATT
	#define ADC_CH_VDD33    	14  			//VBAT,VDD33,VIO33=3PIN,QFN48
#elif(ZQ_M0_MAINBOARD == MBT_582_8850_md) // 2 = akm/md/hsq old type
	// define ADC channel
	#define ADC_CH_NTC1     	7  				//TEM_SENSOR1 使用AIO_1
	#define ADC_CH_NTC2     	0x80 			//TEM_SENSOR2 - 通道7 无效
	#define ADC_CH_BATT     	1  				//ADC_BATT
	#define ADC_CH_VDD33    	14  			//VBAT,VDD33,VIO33=3PIN,QFN48
#elif(ZQ_M0_MAINBOARD == MBT_582_8850_326) // 3 = zy326 
	// define ADC channel
	#define ADC_CH_NTC1     	10 				//TEM_SENSOR1
	#define ADC_CH_NTC2     	0x80 			//TEM_SENSOR2 - 通道9 无效
	#define ADC_CH_BATT     	2  				//ADC_BATT
	#define ADC_CH_VDD33    	14  			//VBAT,VDD33,VIO33=3PIN,QFN48
#else
	#error "Must define m0 mainboard type!"
#endif

// define display driver
#if (ZQ_DISPLAY_PANEL_TYPE == DPT_INTEGRAL_3 || ZQ_DISPLAY_PANEL_TYPE == DPT_INTEGRAL_0 || ZQ_DISPLAY_PANEL_TYPE == DPT_INTEGRAL_4 || ZQ_DISPLAY_PANEL_TYPE == DPT_INTEGRAL_3y)	// 一体显示TM1618驱动
	#include "drv_disp_key_tm1618.h"
#elif(ZQ_DISPLAY_PANEL_TYPE == DPT_SPLIT_1 || ZQ_DISPLAY_PANEL_TYPE == DPT_SPLIT_2 || ZQ_DISPLAY_PANEL_TYPE == DPT_SPLIT_1x)	// 分体显示1键和2键TM1628驱动
	#include "drv_disp_key_tm1628.h"
#elif(ZQ_DISPLAY_PANEL_TYPE == DPT_INTEGRAL_326)								// 一体显示M582驱动
	#include "drv_disp_key_mcu582.h"
#endif 




#define ZQ_PANEL_DIGITAL_3 (ZQ_DISPLAY_PANEL_TYPE == DPT_INTEGRAL_0 || ZQ_DISPLAY_PANEL_TYPE == DPT_INTEGRAL_3 || ZQ_DISPLAY_PANEL_TYPE == DPT_INTEGRAL_4 || ZQ_DISPLAY_PANEL_TYPE == DPT_INTEGRAL_3y || ZQ_DISPLAY_PANEL_TYPE == DPT_INTEGRAL_326) // 3 digital display


// M0 parameters description - unit definition. 
typedef enum {
	PMU_N = 1,	// 无单位
	//PMU_N1,		// 无单位, 精度0.1
	PMU_C,		// 1℃增减, x10存储
	PMU_C1,	// 0.1℃增减, x10存储
	PMU_DC,		// delta温度值, 1℃, x10存储; 使用时要某个基础值做加运算，比如1198的高温报警PM_F5
	PMU_S,		// 秒
	PMU_S1,		// 10秒
	PMU_M,		// 分
	PMU_H,		// 时
	PMU_PS,		// 密码显示, AKM要求显示个位数时候，十位要补零
	PMU_PI,		// param item, 特殊, 不会出现spec参数定义中，只有通知ParamAdjustValue调节的不是参数值而是参数项时候用到，这时候调节不支持长按快进


	PMU_R,		// read only，and following are all read only params
	PMU_NA,		// 空参数，隐藏项, 参数不显示, 系统也不会使用，纯粹只是保留
	PMU_IM,		// implicit params, ap will use it normally except display 
	// PMU_IM1,	// implicit params, ap will use it normally except display, 精度0.1

	PMU_NX,		// spec要求保留参数正常显示, 但是系统不使用
	//PMU_NX1,	// spec要求保留参数正常显示, 但是系统不使用, 精度0.1


	PMU_F1,			// 故障代码查看
	PMU_F2,			// 4G信号强度查看 
	PMU_Ur,			// 数组下标型，特指 Ur参数 -- M0版本号-CAT1版本号
	PMU_LC,			// 拉温模式, 缺省值为关闭=0, 进入这种参数不显示value，而是触发某种功能
	PMU_NV,			// no value, 比如手动（强制）化霜, 进入这种参数不显示value，而是触发某种功能

} PM_UNIT;
#define PMU_IS_READ_ONLY(x) ((x) >= PMU_R)				// check if read only parameter
#define PMU_IS_X10(x) ((x) == PMU_C || (x) == PMU_DC)	// check if x10 parameters，eg. ℃
#define PMU_IS_SHOW(x) ((x) != PMU_NA && (x) != PMU_IM && (x) != PMU_PS)	// check if show parameters to user for selection

#define ZQM_PM_IDX_NA (0x0)		// not available parameter, 用来应对spec要求保留参数正常显示, 但是系统不使用的情况
#define ZQM_PM_MAP(field) ((uint8_t)(size_t)(&(((ZqmPmIdx *)0)->field)))
// #define PM_NUM (sizeof(pms_spec) / sizeof(pms_spec[0]))
extern const uint8_t PM_NUM;
// m0 spec parameters description. describe the parameters name, value, min, max, unit, map
typedef struct {
	char name[4];
	short val;		// value, can be modified by user and saved to flash
	short min;
	short max;
	uint8_t unit:6;
	uint8_t perm:2;	// modified permission, 0:read only, 1: local modify, 2: remote modify, 3: both
	uint8_t map;
}ZqmPmSpec;
// map: M0 ctrl parameters(defined by ap) index -> M0 spec parameters(spec defined), 
// value ZQM_PM_IDX_NA(0xFF) means not available related userparameter, ctrl system will use inner default value.
typedef struct {
	// 温度控制参数
	uint8_t ts;	//设定温度; r1~r2; ℃
	uint8_t r1;	//设定温度最小值, n~TS ℃
	uint8_t r2;	//设定温度最大值, TS~n ℃
	uint8_t ad;	//报警延时, min
	uint8_t ah;	//高温报警值, ℃
	uint8_t al;	//低温报警值, ℃
	uint8_t as;	//上电报警延时, H
	// 压缩机/制热器控制参数
	uint8_t c1;	//温度上回差, .1℃
	uint8_t c2;	//温度下回差, .1℃
	uint8_t c3;	//传感器故障开机时间, M
	uint8_t c4;	//传感器故障停机时间, M
	uint8_t c5;	//显示温度补偿值, .1℃
	uint8_t c6;	//化霜显示解锁时间, H
	uint8_t c7;	//最小停机时间, M
	uint8_t c8;	//开停机补偿, ℃
	uint8_t cd;	// 上电延时启动 M
	uint8_t cf;	// 压机强制运行 H
	uint8_t mtc;//测量温度补偿 .1℃ 
	// 除霜参数 自然/电热化霜机型(1004)
	uint8_t d1;	//自然化霜/压机保护周期, H
	uint8_t d2;	//自然化霜/压机保护时间, M
	uint8_t d3;	//加热化霜-化霜周期, H
	uint8_t d4;	//自然/加热化霜-排水时间, M
	uint8_t d5;	//加热化霜-预冷时间, M
	uint8_t d6;	//加热化霜-退出温度, ℃
	uint8_t d7;	//加热化霜-上限时间, M
	uint8_t d8;	//强制手动化霜-时间, M
	// 功能参数
	uint8_t f1;	//故障代码查看
	uint8_t f2;	//4G信号强度查看, 0-31 
	uint8_t f3;	//电池电量查看, 0-100, % 
	uint8_t f4;	//软件版本, M0和-Cat1切换 
	uint8_t ps;	// 密码配置
	uint8_t h4;	// 蜂鸣器开关
	uint8_t dm;	// 显式模式参数
	uint8_t lc;	// 拉温模式, 缺省值为关闭=0, 
	// 特殊的/后来添加的
	uint8_t f7;	//非营业模块开始时间, H
	uint8_t f8;	//非营业模块结束时间, H
	uint8_t f9;	//非营业模块智能模式, N
	uint8_t tr;	//非营业模式设定温度, ℃

	// uint8_t ps;	// 控制器软件开关
	// uint8_t pm;	// 控制器模式: 冷藏/冷冻/制热
} ZqmPmIdx;
// M0 ctrl parameters(defined by ap), 
typedef struct {
	// 温度控制参数
	short ts;	//设定温度; r1~r2; ℃
	short r1;	//设定温度最小值, n~TS ℃
	short r2;	//设定温度最大值, TS~n ℃
	short ad;	//报警延时, min
	short ah;	//高温报警值, ℃
	short al;	//低温报警值, ℃
	short as;	//上电报警延时, H
	// 压缩机/制热器控制参数
	short c1;	//温度上回差, .1℃
	short c2;	//温度下回差, .1℃
	short c3;	//传感器故障开机时间, M
	short c4;	//传感器故障停机时间, M
	short c5;	//显示温度补偿值, .1℃
	short c6;	//化霜显示解锁时间, H
	short c7;	//最小停机时间, M
	short c8;	//开停机补偿, ℃
	short cd;	// 上电延时启动 M
	short cf;	// 压机强制运行 H
	short mtc;	//测量温度补偿 .1℃ 
	// 除霜参数 自然/电热化霜机型(1004)
	short d1;	//自然化霜/压机保护周期, H
	short d2;	//自然化霜/压机保护时间, M
	short d3;	//加热化霜-化霜周期, H
	short d4;	//自然/加热化霜-排水时间, M
	short d5;	//加热化霜-预冷时间, M
	short d6;	//加热化霜-退出温度, ℃
	short d7;	//加热化霜-上限时间, M
	short d8;	//强制手动化霜-时间, M
	// 功能参数
	short f1;	//故障代码查看
	short f2;	//4G信号强度查看, 0-31 
	short f3;	//电池电量查看, 0-100, % 
	short f4;	//软件版本, M0和-Cat1切换 
	short ps;	// 密码配置
	short h4;	// 蜂鸣器开关
	short dm;	// 显式模式参数
	short lc;	// 拉温模式, 缺省值为关闭=0, 
	// 特殊的/后来添加的
	short f7;	//非营业模块开始时间, H
	short f8;	//非营业模块结束时间, H
	short f9;	//非营业模块智能模式, N
	short tr;	//非营业模式设定温度, ℃

	// uint8_t ps;	// 控制器软件开关
	// uint8_t pm;	// 控制器模式: 冷藏/冷冻/制热
} ZqmPmCtrl;

extern short pm_ur_num[2];						// 数字形式的联合版本号，m0-cat1 类似10200-10500
extern char* pm_f1_val[10];
extern ZqmPmSpec pms_spec[];
extern ZqmPmIdx pm_idx;
extern ZqmPmCtrl pm_ctrl;

// set parameter value, return true if modified value in fact(used to just is need to save), or false
// idx: parameter index (pm_idx), value: new value
extern bool PmSetValue(uint8_t idx, short value);
// force to set parameter value, without checking input value
// idx: parameter index (pm_idx), value: new value, min and max value
void PmForceSetValue(uint8_t idx, short value, short min, short max);
// save all parameters to flash
extern void PmSave(void);
// load all parameters from flash
extern void PmLoad(void);
// load the version code value
void PmLoadUrCode(void);
// Dynamically load the error code value
void PmLoadErrCode(void);
